package cn.study.base;

import com.lmax.disruptor.EventTranslatorOneArg;
import com.lmax.disruptor.RingBuffer;

import java.nio.ByteBuffer;

/**
 * Disruptor 3.0提供了lambda式的API。这样可以把一些复杂的操作放在Ring Buffer，
 * 所以在Disruptor3.0以后的版本最好使用Event Publisher或者Event Translator来发布事件
 */
public class LongEventProducerWithTranslator {

	/**
	 * 此类简化了LongEventProducer中onData方法的步骤
	 */

	private final RingBuffer<LongEvent> ringBuffer;

	public LongEventProducerWithTranslator(RingBuffer<LongEvent> ringBuffer) {
		this.ringBuffer = ringBuffer;
	}

	// 一个translator可以看做一个事件初始化器，publicEvent方法会调用它
	// 填充Event
	private static final EventTranslatorOneArg<LongEvent, ByteBuffer> TRANSLATOR =
			new EventTranslatorOneArg<LongEvent, ByteBuffer>() {
				@Override
				public void translateTo(LongEvent event, long sequeue, ByteBuffer buffer) {
					/**
					 * 重写此类的translateTo方法相当于disruptor帮我们简化了前2个步骤,
					 * 直接就返回了LongEvent实例对象给了我们
					 *
					 * 1.可以把ringBuffer看做一个事件队列，那么next就是得到下面一个事件槽（也就是一个下标索引）
					 * long sequence = ringBuffer.next();
					 * 2.用上面的索引取出一个空的事件用于填充（获取该序号对应的事件对象）
					 * 就是disruptor在槽里实例化了一个自己定义的数据对象并返回
					 * LongEvent event = ringBuffer.get(sequence);
					 */


					// 3.获取要通过事件传递的业务数据
					// 实际操作disruptor实例化数据对象，处理业务逻辑
					event.setValue(buffer.getLong(0));
					System.out.println("producer: " + event.getValue());
				}
			};

	public void onData(ByteBuffer buffer){
		// 4.发布事件（必写）
		ringBuffer.publishEvent(TRANSLATOR, buffer);
	}

}
